package com.wuliu.system.service.impl;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import javax.annotation.Resource;

import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson2.JSONObject;
import com.wuliu.common.utils.DateUtils;
import com.wuliu.common.utils.StringUtils;
import com.wuliu.system.domain.TolWechatTemplate;
import com.wuliu.system.domain.dto.WxPushDto;
import com.wuliu.system.mapper.TolWechatTemplateMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import com.wuliu.system.mapper.TolPushMapper;
import com.wuliu.system.domain.TolPush;
import com.wuliu.system.service.ITolPushService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

/**
 * 公众号/小程序推送记录Service业务层处理
 *
 * @author realue
 * @date 2023-10-10
 */
@Service
public class TolPushServiceImpl extends ServiceImpl<TolPushMapper, TolPush> implements ITolPushService {
    private static final Logger logger = LoggerFactory.getLogger(TolPushServiceImpl.class);
    @Resource
    private TolPushMapper tolPushMapper;
    @Resource
    private TolWechatTemplateMapper tolWechatTemplateMapper;

    /**
     * 查询公众号/小程序推送记录
     *
     * @param id 公众号/小程序推送记录主键
     * @return 公众号/小程序推送记录
     */
    @Override
    public TolPush selectTolPushById(String id) {
        return tolPushMapper.selectTolPushById(id);
    }

    /**
     * 查询公众号/小程序推送记录列表
     *
     * @param tolPush 公众号/小程序推送记录
     * @return 公众号/小程序推送记录
     */
    @Override
    public List<TolPush> selectTolPushList(TolPush tolPush) {
        return tolPushMapper.selectTolPushList(tolPush);
    }

    /**
     * 新增公众号/小程序推送记录
     *
     * @param tolPush 公众号/小程序推送记录
     * @return 结果
     */
    @Override
    public int insertTolPush(TolPush tolPush) {
        return tolPushMapper.insertTolPush(tolPush);
    }

    /**
     * 修改公众号/小程序推送记录
     *
     * @param tolPush 公众号/小程序推送记录
     * @return 结果
     */
    @Override
    public int updateTolPush(TolPush tolPush) {
        return tolPushMapper.updateTolPush(tolPush);
    }

    /**
     * 批量删除公众号/小程序推送记录
     *
     * @param ids 需要删除的公众号/小程序推送记录主键
     * @return 结果
     */
    @Override
    public int deleteTolPushByIds(String[] ids) {
        return tolPushMapper.deleteTolPushByIds(ids);
    }

    /**
     * 删除公众号/小程序推送记录信息
     *
     * @param id 公众号/小程序推送记录主键
     * @return 结果
     */
    @Override
    public int deleteTolPushById(String id) {
        return tolPushMapper.deleteTolPushById(id);
    }

    /**
     * 生成微信待推送消息
     *
     * @param wxPush
     */
    @Async
    @Override
    public void createTolPush(WxPushDto wxPush) {
        logger.info("insert_push_data:{}", JSONObject.toJSONString(wxPush));
        if (!wxPush.isValid()) {
            logger.error("用户openid、账套号、业务类型、类型不能为空");
            return;
        }
        try {
            List<TolPush> tolPushes = new ArrayList<>();
            TolWechatTemplate template = new TolWechatTemplate();
            template.setSysAccount(wxPush.getBasCust().getSysAccount());
            List<TolWechatTemplate> tolWechatTemplates = tolWechatTemplateMapper.selectTolWechatTemplateList(template);
            if (wxPush.getType() == 1 || wxPush.getType() == 3) {
                TolWechatTemplate tolWechatTemplate = tolWechatTemplates.stream().filter(t -> t.getTmpType() == 1 && Objects.equals(t.getBusiType(), wxPush.getBusiType())).findFirst().orElse(null);
                if (null != tolWechatTemplate) {
                    tolPushes.add(buildTolPush(tolWechatTemplate, wxPush));
                } else {
                    logger.info("业务类型为{}的小程序消息模板不存在", wxPush.getBusiType());
                }
            }
            if (wxPush.getType() == 2 || wxPush.getType() == 3) {
                TolWechatTemplate tolWechatTemplate = tolWechatTemplates.stream().filter(t -> t.getTmpType() == 2 && Objects.equals(t.getBusiType(), wxPush.getBusiType())).findFirst().orElse(null);
                if (null != tolWechatTemplate) {
                    tolPushes.add(buildTolPush(tolWechatTemplate, wxPush));
                } else {
                    logger.info("业务类型为{}的公众号消息模板不存在", wxPush.getBusiType());
                }
            }
            if (StringUtils.isNotEmpty(tolPushes)) {
                tolPushMapper.batchSave(tolPushes);
            }
        } catch (Exception e) {
            logger.error("创建推送记录失败:{}", e.getMessage());
        }
    }

    /**
     * @param template
     * @param wxPush
     * @return
     */
    private TolPush buildTolPush(TolWechatTemplate template, WxPushDto wxPush) throws IllegalAccessException {
        String tmpContent = template.getTmpContent();
        Field[] fields = wxPush.getClass().getDeclaredFields();
        for (int i = 0; i < fields.length - 1; i++) {
            fields[i].setAccessible(true);
            String tmpStr = "#" + fields[i].getName() + "#";
            if (tmpContent.contains(tmpStr)) {
                tmpContent = tmpContent.replaceAll(tmpStr, Objects.isNull(fields[i].get(wxPush)) ? "" : fields[i].get(wxPush).toString().replace("\"", ""));
            }
        }
        TolPush tolPush = new TolPush();
        tolPush.setId(IdUtil.randomUUID());
        tolPush.setTmpId(template.getTmpId());
        tolPush.setPushContent(tmpContent);
        tolPush.setStatus(0);
        if (wxPush.getType() == 1 || wxPush.getType() == 3) {
            tolPush.setPushType(1);
            tolPush.setOpenId(wxPush.getBasCust().getAppletOpenId());
        } else if (wxPush.getType() == 2 || wxPush.getType() == 3) {
            tolPush.setPushType(2);
            tolPush.setOpenId(wxPush.getBasCust().getPublicOpenId());
        }
        tolPush.setSysAccount(wxPush.getBasCust().getSysAccount());
        tolPush.setCreateDt(DateUtils.getTime());
        tolPush.setJumpUrl(template.getTmpJumpUrl());
        return tolPush;
    }

    /**
     * 查询待推送消息
     * @return
     */
    @Override
    public List<TolPush> selectTolPushToSend() {
        return tolPushMapper.selectTolPushToSend();
    }
}
